/**
 * 响应组件
 * 标准化API响应格式和错误处理
 */
class ResponseComponent {

  /**
   * 成功响应
   * @param {Object} res Express响应对象
   * @param {Object} data 响应数据
   * @param {string} message 响应消息
   * @param {number} statusCode HTTP状态码
   * @returns {Object} 响应结果
   */
  static success(res, data = null, message = '操作成功', statusCode = 200) {
    const response = {
      success: true,
      message,
      timestamp: new Date().toISOString(),
      ...(data && { data })
    };

    return res.status(statusCode).json(response);
  }

  /**
   * 失败响应
   * @param {Object} res Express响应对象
   * @param {string} message 错误消息
   * @param {number} statusCode HTTP状态码
   * @param {Object} error 错误详情
   * @returns {Object} 响应结果
   */
  static error(res, message = '操作失败', statusCode = 500, error = null) {
    const response = {
      success: false,
      message,
      timestamp: new Date().toISOString(),
      ...(error && { error })
    };

    return res.status(statusCode).json(response);
  }

  /**
   * 分页响应
   * @param {Object} res Express响应对象
   * @param {Array} data 数据数组
   * @param {Object} pagination 分页信息
   * @param {string} message 响应消息
   * @returns {Object} 响应结果
   */
  static paginated(res, data, pagination, message = '获取数据成功') {
    const response = {
      success: true,
      message,
      data,
      pagination,
      timestamp: new Date().toISOString()
    };

    return res.status(200).json(response);
  }

  /**
   * 创建成功响应
   * @param {Object} res Express响应对象
   * @param {Object} data 创建的数据
   * @param {string} message 响应消息
   * @returns {Object} 响应结果
   */
  static created(res, data, message = '创建成功') {
    return this.success(res, data, message, 201);
  }

  /**
   * 验证错误响应
   * @param {Object} res Express响应对象
   * @param {Array|string} errors 验证错误信息
   * @param {string} message 错误消息
   * @returns {Object} 响应结果
   */
  static validationError(res, errors, message = '数据验证失败') {
    const response = {
      success: false,
      message,
      errors: Array.isArray(errors) ? errors : [errors],
      timestamp: new Date().toISOString()
    };

    return res.status(400).json(response);
  }

  /**
   * 未找到资源响应
   * @param {Object} res Express响应对象
   * @param {string} message 错误消息
   * @returns {Object} 响应结果
   */
  static notFound(res, message = '资源不存在') {
    return this.error(res, message, 404);
  }

  /**
   * 未授权响应
   * @param {Object} res Express响应对象
   * @param {string} message 错误消息
   * @returns {Object} 响应结果
   */
  static unauthorized(res, message = '未授权访问') {
    return this.error(res, message, 401);
  }

  /**
   * 禁止访问响应
   * @param {Object} res Express响应对象
   * @param {string} message 错误消息
   * @returns {Object} 响应结果
   */
  static forbidden(res, message = '禁止访问') {
    return this.error(res, message, 403);
  }

  /**
   * 冲突响应（如资源已存在）
   * @param {Object} res Express响应对象
   * @param {string} message 错误消息
   * @returns {Object} 响应结果
   */
  static conflict(res, message = '资源冲突') {
    return this.error(res, message, 409);
  }

  /**
   * 服务器内部错误响应
   * @param {Object} res Express响应对象
   * @param {Error} error 错误对象
   * @param {string} message 错误消息
   * @returns {Object} 响应结果
   */
  static internalError(res, error, message = '服务器内部错误') {
    console.error('服务器错误:', error);
    
    const response = {
      success: false,
      message,
      timestamp: new Date().toISOString()
    };

    // 开发环境下返回详细错误信息
    if (process.env.NODE_ENV === 'development') {
      response.error = {
        message: error.message,
        stack: error.stack
      };
    }

    return res.status(500).json(response);
  }

  /**
   * 处理业务组件返回的结果
   * @param {Object} res Express响应对象
   * @param {Object} result 业务组件返回的结果
   * @param {number} successStatusCode 成功时的状态码
   * @returns {Object} 响应结果
   */
  static handleComponentResult(res, result, successStatusCode = 200) {
    if (result.success) {
      // 如果有分页信息，使用分页响应
      if (result.pagination) {
        return this.paginated(res, result.data, result.pagination, result.message);
      }
      
      // 普通成功响应
      return this.success(res, result.data, result.message, successStatusCode);
    } else {
      // 根据错误类型返回不同的状态码
      let statusCode = 500;
      
      if (result.message.includes('验证失败') || result.errors) {
        statusCode = 400;
      } else if (result.message.includes('不存在') || result.message.includes('未找到')) {
        statusCode = 404;
      } else if (result.message.includes('已存在') || result.message.includes('冲突')) {
        statusCode = 409;
      } else if (result.message.includes('权限') || result.message.includes('禁止')) {
        statusCode = 403;
      } else if (result.message.includes('未授权') || result.message.includes('登录')) {
        statusCode = 401;
      }

      if (result.errors) {
        return this.validationError(res, result.errors, result.message);
      }
      
      return this.error(res, result.message, statusCode, result.error);
    }
  }

  /**
   * 处理异步操作的错误
   * @param {Function} asyncFn 异步函数
   * @returns {Function} 包装后的中间件函数
   */
  static asyncHandler(asyncFn) {
    return (req, res, next) => {
      Promise.resolve(asyncFn(req, res, next)).catch(next);
    };
  }

  /**
   * 全局错误处理中间件
   * @param {Error} err 错误对象
   * @param {Object} req Express请求对象
   * @param {Object} res Express响应对象
   * @param {Function} next Next函数
   * @returns {Object} 错误响应
   */
  static globalErrorHandler(err, req, res, next) {
    console.error('全局错误处理:', err);

    // 数据库连接错误
    if (err.code === 'ECONNREFUSED' || err.code === 'ER_ACCESS_DENIED_ERROR') {
      return ResponseComponent.error(res, '数据库连接失败', 503);
    }

    // 语法错误
    if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
      return ResponseComponent.error(res, '请求数据格式错误', 400);
    }

    // 默认服务器错误
    return ResponseComponent.internalError(res, err);
  }

  /**
   * 404 处理中间件
   * @param {Object} req Express请求对象
   * @param {Object} res Express响应对象
   * @returns {Object} 404响应
   */
  static notFoundHandler(req, res) {
    return ResponseComponent.notFound(res, `路由 ${req.originalUrl} 不存在`);
  }
}

module.exports = ResponseComponent; 